from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label

from kivy.uix.widget import Widget
from kivy.properties import BooleanProperty, NumericProperty, ObjectProperty, StringProperty


import collections

from kivyext.simplepopup import SimplePopup
from world.wineObjects import BottleBase, WineObjectTranslation
import guiCommon, levinCommon

from world.worldArea import WorldArea

class SynchroButton(Widget):
    arrow_width = NumericProperty(0)
    reset_width = NumericProperty(0)
    item = None

    button_down = StringProperty('')
    def on_touch_down(self,touch):
        if self.collide_point(*touch.pos) :
            x = touch.pos[0] - self.x
            if x < self.arrow_width :
                self.button_down = 'left'
                self.item.to_left()
            elif x > self.width - self.arrow_width:
                self.button_down = 'right'
                self.item.to_right()
            else:
                self.button_down = 'center'
                self.item.reset()
            return True
        else:
            return super(SynchroButton, self).on_touch_down(touch)

    def on_touch_up(self,touch):
        self.button_down = ''
        return False


class SynchroItem(BoxLayout):
    left_label  = ObjectProperty(None)
    right_label = ObjectProperty(None)
    button = ObjectProperty(None)
    att_label = ObjectProperty(None)
    
    left_bottle  = None
    right_bottle = None
    src_dest = None
    att = None
    translationDict = WineObjectTranslation
    
    def __init__(self, **kargs):
        #print 'MyLAbel ', kargs
        super(SynchroItem, self).__init__(**kargs)
        self.button.item = self
        #self.right_label.item = self
        
    def set_bottle(self, l,r):
        self.left_bottle = l
        self.right_bottle = r

    def updateAtt(self,att):
        self.left_label.text = unicode(getattr(self.left_bottle, att))
        self.right_label.text = unicode(getattr(self.right_bottle, att))
        self.att_label.text = self.translationDict[att]
        self.att = att

    def to_left(self):
        self.left_label.text = self.right_label.text
        self.src_dest  = self.right_bottle, self.left_bottle

    def to_right(self):
        self.right_label.text = self.left_label.text
        self.src_dest  = self.left_bottle, self.right_bottle

    def reset(self):
        self.updateAtt(self.att)

    def applySynchro(self):
        if self.src_dest:
            src, dest = self.src_dest
            setattr( dest, self.att, getattr(src, self.att) )

import levinCommon
class TastingSynchroItem(SynchroItem):
    def updateAtt(self,att):
        self.left_label.text = unicode(getattr(self.left_bottle, att))
        self.right_label.text = unicode(getattr(self.right_bottle, att))
        self.att_label.text =  _("Tasting on %s : ")%(levinCommon.dateFromOrdinal(self.left_bottle.date))+ self.translationDict[att] 
        self.att = att

    pass

import world.wineTasting as wineTasting
SynchroItem.translationDict.update((a,ad) for (a,ad) in wineTasting.OrderedTastingAtt.iterAll() )

class SynchroWidget(BoxLayout):
    next_button = ObjectProperty(None)
    cancel_button = ObjectProperty(None)
    wine_desc = ObjectProperty(None)
    synchro_box = ObjectProperty(None)

    _synchroItemList = []
    _tastingSynchroItemList = []
    
    _conflicting_bottles = []

    stop = False

    def __init__(self, **kargs):
        super(SynchroWidget, self).__init__(**kargs)
        self.register_event_type('on_all_synchronized')
        
    def on_all_synchronized(self):
        pass

    def fromDiffering(self, w1,w2):
        differing_att = collections.defaultdict(list)

        w1.compare(w2,differing_att)
        differing_att = differing_att[w1]
        print '   ___ fromDiffering ',w1,w2, differing_att
            
        self.wine_desc.text = w1.parentArea.getRegionOrAbove().localname +', '+w1.parentArea.localname+', '+w1.cru_name
        SynchroItem.left_bottle = w1
        SynchroItem.right_bottle = w2
        self.resize_synchroItemList( len( differing_att) )

        self.synchro_box.clear_widgets()
        hasTasting = '_tastings_' in differing_att
        if hasTasting:
            differing_att.remove('_tastings_')
        for att,it in zip(differing_att,self._synchroItemList):
            it.updateAtt(att)
            self.synchro_box.add_widget(it)

        if not hasTasting:
            return

        
        diff_tastings = [  ]
        def _f( w, wother, tother):  # temporary func to deal with removed tastings
            if tother.tastingId not in w.removedTastings:
                w.addTasting( tother )
            else:
                wother.removeTasting( tother)

        for t1,t2 in w1.compareTasting(w2):
            if None not in (t1,t2) :
                diff_tastings.append( (t1,t2) )
            else:
                if t1 is None : _f( w1, w2, t2)
                if t2 is None : _f( w2, w1, t1)
            
        all_tastings = []
        for t1,t2 in diff_tastings:
            diff_att = t1.differing_att(t2)
            all_tastings += [ (t1,t2,att) for att in diff_att ]
        self.resize_tastingSynchroItemList( len(all_tastings) )
        for (t1,t2,att),it in zip(all_tastings,self._tastingSynchroItemList):
            it.set_bottle(t1,t2)
            it.updateAtt(att)
            self.synchro_box.add_widget(it)
            
        
        
    def resize_synchroItemList(self, n):
        if n<len(self._synchroItemList):
            return
        self._synchroItemList.extend( SynchroItem() for i in range(n - len(self._synchroItemList) ))

    def resize_tastingSynchroItemList(self, n):
        if n<len(self._tastingSynchroItemList):
            return
        self._tastingSynchroItemList.extend( TastingSynchroItem() for i in range(n - len(self._tastingSynchroItemList) ))

    def next_bottle(self):
        for it in self.synchro_box.children:
            it.applySynchro()
        print '  next bottle ', self._conflicting_bottles            

        try:    
            self.fromDiffering( * self.iter_conflict.next() )
            print ' to next '
        except StopIteration:
            self.dispatch('on_all_synchronized')
            print ' ended '
    def start_iter_conflict(self):
        def _f():
            for w1,w2 in self._conflicting_bottles:
                yield w1,w2
        self.iter_conflict = _f()
        self.fromDiffering(* self.iter_conflict.next() )

class SynchroPopup(SimplePopup):

    def __init__(self, **kargs):
        sw=SynchroWidget()
        kargs['content'] = [sw]
        self.syncW = sw
        super(SynchroPopup, self).__init__(**kargs)
        sw.bind(on_all_synchronized = self.dismiss)

    
    def set_conflicting(self, cL):
        if cL == []:
            return
        self.syncW.cancel_button.bind(on_press = self.dismiss)        
        self.syncW._conflicting_bottles = cL
        self.syncW.start_iter_conflict()

from kivy.factory import Factory
for cls in [SynchroPopup, SynchroWidget,SynchroButton]:
    Factory.register(cls.__name__, cls=cls)


guiCommon.load_kv_file('synchroGui.kv')

theSynchroPopup = None
def resolveByGui(self, conflict ):
    if conflict == []:
        return
    global theSynchroPopup
    second = theSynchroPopup != None
    if not second:
        theSynchroPopup = SynchroPopup()
    theSynchroPopup.set_conflicting(conflict)    
    if self._saveSynchronizedFile:
        theSynchroPopup.bind(on_dismiss = self._saveSynchronizedFile)
    theSynchroPopup.open()

from kivy.uix.popup import Popup

def start_synchro_choosing_file(*l):
    # getdir
    from os.path import dirname
    from kivy.uix.filechooser import FileChooserIconView
    #f = FileChooserIconView(filters=['*user.pk'], path=levinCommon.application.config.get('Paths', 'Images'))
    f = FileChooserIconView(filters=['*user.pk'], path=levinCommon.guessSynchroPath())
    from kivy.uix.popup import Popup       
    pop =  guiCommon.LeVinAlert( addValidB = False,title=_('Choose a file') , size_factor=2./3, validText='') #, size_hint=(None,None),size=(Window.width*2/3,Window.height*2/3))
    #pop =  Popup( title=_('Choose a file') , size_factor=2./3, validText='') #, size_hint=(None,None),size=(Window.width*2/3,Window.height*2/3))
    pop.content = f
    def file_chosen(*l):
        print ' PPPPPPPPPPP ',l
        theF = f.selection[0]
        
        pop.dismiss()

        WorldArea.resolveConflict = resolveByGui

        levinCommon.wineWorld.synchronizeWithFile(  theF  )
        
        
        
    f.bind( on_submit = file_chosen)
    pop.cancelB.bind( on_press = pop.dismiss)
    pop.open()
    
